home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Plus Special 17
/
AMIGAplus Sonderheft 17 (1999)(ICP)(DE)[!].iso
/
PD
/
Spiele
/
Graal
/
GRAAL_Tutorial.text
< prev
next >
Wrap
Text File
|
1996-10-14
|
107KB
|
2,872 lines
GRAAL - THE MANUAL
___________
===========
\ /
| |
| |
| |
| |
\_ _/
| |
| |
| |
| |
| |
/ \
=======
A Tutorial Manual
for GRAAL 2
by Per Thulin
GRAAL is the Swedish spelling of GRAIL
- A suitable symbol and frequent guest
in adventure games!
© Performance Software 1995/1996
CONTENTS
========
1 INTRODUCTION
1.1 COPYRIGHT NOTICE(S)
1.2 ABOUT THE MANUAL
1.3 RELEASE INFO
1.4 KNOWN BUGS
2 (FINALLY:) THE INTRODUCTION
2.1 SO, WHAT IS GRAAL?
2.2 OTHER TOOLS OF THE TRADE
2.3 THE THINGS THAT MAKE A GRAAL
2.4 GRAAL SCRIPT FILES
2.5 THE GRAAL.MAIN FILE
2.6 THE .ROOM FILES
2.7 THE .SECTION FILES
2.8 THE .SCENE FILES
2.9 THE .PTRN FILES
2.10 RUNNING THE ADVENTURE
3 STARTING ON AN ADVENTURE
3.1 STARTING ON THE GRAAL.MAIN FILE
3.2 THE HERO - WHAT A CHARACTER!
3.3 BASICS ABOUT IMAGES AND BOBS
3.4 THE IMAGES IN THE GRAAL.MAIN FILE
4 "A ROOM! A ROOM! A KINGDOM FOR A ROOM!"
5 THE OBJECT MATTER
6 SECTION OBJECTS AND BOBS
7 (LIGHTS! CAMERA! ACTION!)
8 USING EXITS
9 THE DACT STATEMENTS
10 HAVING A CHAT
11 MASTER CLASS: CHARACTER AND GRAPHICS DESIGN
11.1 SIZE
11.2 COLOUR
11.3 DESIGNING ANIMATIONS
11.4 ALL ABOUT 3D AND HOTSPOTS
12 MASTER CLASS: CUTSCENES
12.1 HOP, SKIP AND JUMP
12.2 NO BREAKS!
12.3 NESTING
13 MASTER CLASS: SPECIAL TECHNIQUES OR "HOW THE HECK DID HE DO THAT?"
13.1 SPEAKING IN A FOREIGN TONGUE
13.2 AN AUTOMATED ROOM
13.3 THE ART OF AVOIDING A SEAGULL
13.4 A SPITTING IMAGE
13.5 A MAP ROOM
13.6 A SMALL GUY
14 MASTER CLASS: HINTS AND TIPS
14.1 FLAGS
15 QUESTIONS AND ANSWERS
SUPPORT TOOLS
A THE ON-LINE MONITOR
A.1 OBJECT CONTROL
A.2 ROOM CONTROL
A.3 DIALOGUE CONTROL
A.4 BACK TO GRAAL
B MACROS
C "PRODUCTIFYING" YOUR ADVENTURES
D THE EDITOR
1 INTRODUCTION
==============
1.1 COPYRIGHT NOTICE(S)
-----------------------
GRAAL 2 is Shareware. If you like it and use it, register and make
me happy!
All rights to the GRAAL system remains with Performance Software and
is copyright © 1996 Per Thulin.
Users of GRAAL may use the system freely to distribute their own
graphic adventures, but are completely forbidden to use any of the
supplied example material - puzzles, characters, animations, or
scenes - in their own work. Quite simply, all material used in your
own GRAAL adventures must be your own!
The shareware version of GRAAL is not crippled in any way, but it is
not quite adapted for professional use, which is explained later in
this manual.
You may not use the unregistered version of GRAAL for commercial
purposes. If you plan on making money from your adventures, you
MUST register GRAAL - and the registered version of GRAAL is really
the only way to package GRAAL adventures in a safe and semi-professional
way, not giving all the game's secrets away in unscrambled script files
and the on-line monitor!
To register, simply send the
equivalent of £15, (or 150 SEK), in cash to:
Per Thulin
Malmtorgsgatan 18
S-653 40 KARLSTAD
SWEDEN
State your current shareware version. You will receive the missing
production tools, and the latest version if changes have been made
to the Shareware version you already have.
GRAAL is coded in Amos Professional. You know it makes sense... :)
Also, let's not forget that Black Legend Craft 1 extension. It made
things that much easier!
(The GRAAL Editor is coded in Blitz 2 Basic. You know it makes even
more sense... ;)
1.2 ABOUT THE MANUAL
--------------------
This manual contains an awful lot of text. Don't be discouraged -
that is simply because each little GRAAL statement carries an awful
lot of power (and because I'm such a blabbermouth), and some sophisticated
initial definitions automate most of the gameplay! Before you get totally
discouraged, print out the following files from the example disk(s):
graal.main
1.section
1.room
If you look at these files, and disregard the abundance of comment
lines starting with /*, you will quickly realise how precious little
GRAAL code is actually needed for the basics of an adventure, and be
able to read on with a lighter heart. Also remember that there is an
editor included making your GRAAL-coding life a lot easier - you don't
have to enter that many tricky parts manually, the editor can help you.
The GRAAL documentation is divided into five main parts:
1. The graal_2.readme file - essential to all who wants to read about
the news in GRAAL 2.
2. This Tutorial Manual.
3. An AmigaGuide on-line reference (graal.guide)
4. The GRAAL Editor documentation (Editor.text)
5. The productification tools documentation (prod.text)
This manual contains:
1. This introductory section, describing what GRAAL is and what it
is not.
2. The tutorial section, describing how GRAAL was used to create the
first seven rooms of the Olaf Longhair adventure (the demo portion of
which is supplied with this release of GRAAL).
3. "Master Classes" - more in-depth discussions on some of the
trickier concepts - dialogues, graphics, and so on.
4. "Q:s and A:s", a section that also will be expanded upon in the
future - provided there are enough people interested!
If you want to play the provided "Olaf" demo AND build your own
Graphic Adventure, I strongly suggest you play the game first!
Because "Olaf" is used as an example throughout the tutorial, some
of the secrets of the demo is given away here. This is also a good
way of deciding whether this kind of stuff is what you want to spend
the rest of your life doing :-)
1.3 RELEASE INFO
----------------
This version of GRAAL has been tested on an A600 with WB 2.05, and
an A1200 with WB 3.0. (If you want to make your own games, you need
at least a standard A1200 and a hard drive)
System Requirements: Hard disk, >2MB RAM and fastmem recommended.
The GRAAL text editor requires WB 2.0 or above.
GRAAL v2 brings you:
* A graphic adventure point'n'click interface along the lines of,
among others, the Indy games and Monkey Island (Trademarks of
LucasArts Ltd.).
* Automation of most of the main character's walking, talking, and
general fiddling around.
* 32- or 64-colour (EHB), automatically scrolling background screens,
320 to 640 pixels wide and 120 pixels high.
* Fully configurable command area and graphics set-up.
* "Unlimited" number of locations (rooms) in a game.
* Room and section data swapped in and out of memory at runtime to
minimise the growth of permanent in-memory data as the adventure
grows.
* Side-view "simulated 3D" scenes with foreground, any level of
middle and background objects.
* Animated objects and characters.
* Pixel-perfect detection of objects.
* A rather intelligent and easy-to-use dialogue system for those
totally silly discussions with sidekick characters we all have come
love so much.
* An equally intelligent and smart but perhaps a little more
difficult-to-grasp floor definition system - for defining legal
movement paths and automatic negotiation of obstacles.
* Cut-scenes.
* Soundtracker style music modules for background music.
* IFF and raw samples for sound effects.
* Run-time error checking (to a degree).
* GRAAL automatically detects if a GRAAL adventure is run from diskette
or hard disk, and adjusts disk swapping and save/load routines
accordingly.
* Also automatically detects extra memory and uses this as cache memory
to avoid unnecessary disk access.
* All tools needed except an art/animation package and (optional)
sound sampler equipment.
* Diskette layout system for automatic copying and labelling of
distribution master diskettes.
* Dynamic on-line monitor and debugger for script testing, on-the-
fly temporary corrections, and examination of the game status.
* A text editor especially constructed to be GRAAL-friendly, with extra
features to help with the editing of the more complex GRAAL statements
The developer's registered version also gives you:
* Optimisation and encryption of distribution files.
* A keyfile disabling the monitor and other development functions for
the final delivery version.
* Extra graphics files offering various "requester looks".
It does NOT bring you:
- Dynamic depth-scaling of characters.
- AGA (but on the other hand, a much broader customer base for your
games. Let's be kind to those ECS users out there! :)
- Multiple character control
( planned for version 334.0. Let's be honest - it hasn't added too
much to the games where it has been used ;-)
1.4 KNOWN BUGS
---------------
* On my A1200/WB3.0, something in GRAAL (and other large, compiled
Amos Pro programs) constantly triggers the Workbench warning sound.
This is a little annoying, and I cannot guarantee that there is a
way to fix it, since the problem lies somewhere within the way Amos
Pro compiles.
However, the remedy is simple enough: Just make sure to turn the
Workbench warning signals off using Prefs before using GRAAL or
playing a GRAAL game.
2 (FINALLY:) THE INTRODUCTION
=============================
Welcome to GRAAL. Maybe thy quest is over!
...or maybe it has just begun. Because, although GRAAL is a powerful
tool, designing a graphic adventure still needs an awful lot of hard
work from your side - all GRAAL does is take most of the actual
coding work out of the job and lets you get on with designing the
story, logic, backgrounds, objects, animated characters and
dialogue! Which, in itself, should keep you busy for quite a while.
GRAAL was mainly invented along with the 7-room demo of the first
ever GRAAL adventure "Olaf Longhair, Part I", delaying the release
of both, but ensuring that GRAAL really works on a full-scale and
rather advanced graphic adventure. Although maybe not quite up to
LucasArts standards, it proves that GRAAL can make at least a
budget-level game any day! And since this manual was written
parallel to the code that went into "Olaf" and GRAAL itself, you
should find everything of importance right here.
2.1 SO, WHAT IS GRAAL?
----------------------
All GRAAL adventures consist of:
* The GRAAL program, which is the "adventure engine". It is named
GRAAL_2 in the development package. When you use it to run a
specific game, it is usually renamed to whatever that adventure
is called.
* GRAAL script files, containing the statements that make up the
adventure. There are different kinds of script files: One
graal.main file, .room files, .section files, .scene files, and
.ptrn files.
* IFF image files, depicting background scenes and object and
character "clip-art".
* A file called diskinfo.graal. This file contains, among other
things, the names of all the other files used in your adventure.
This file is used by GRAAL to locate files and handle disk
swapping in an intelligent way if your game gets so big it does
not fit onto one disk.
* Optionally, soundtracker music modules and sample banks.
2.2 OTHER TOOLS OF THE TRADE
----------------------------
If you don't have AmigaGuide (or Multiview - WB 3 and above), get hold
of it NOW. You'll need it to read the on-line command reference.
You will not go far without a good paint program like Deluxe Paint,
Brilliance or Personal Paint to create all backgrounds, objects and
animations. An image processing program like Photopaint, Image FX
or ADPro is a good complement.
To take some of the work out of the backdrop scene creation, why not
use a 3D modelling and rendering package? (Believe it or not, there
are some good ones that are freeware, even - POV-ray, for instance.)
A sound sampler and software could also come in handy, as could a
scanner or digitizer. But hey, it's up to you. Or rather, your
wallet.
2.3 THE THINGS THAT MAKE A GRAAL
--------------------------------
Because there are a lot of things in the GRAAL system to keep track
of, and you need almost all of it to make the adventure work, the
manual will try to explain most of the stuff in the tutorial form,
followed by in-depth discussions on a number of the trickier
subjects and concepts. There is also an on-line command reference
in Amigaguide format, which is a necessary complement to this manual,
and which will be vital once you get hang of things in general. Also,
the Olaf 1 demo provides you with well commented script files of all
types. These demonstrate almost all major GRAAL techniques. (Beware:
READ THE COPYRIGHT NOTICE!)
But first, a quick general look at the general structure of a
GRAAL game:
2.4 GRAAL SCRIPT FILES
----------------------
The GRAAL code needed to make an adventure tick is contained in a
number of script files. It is a compact language; if it wasn't for
the heavy commenting, they would not take up too much space at all!
There are different types of script files, each controlling
a different portion of the game. Their relationships form a tree-
shaped structure, like this:
+-----------------+
! GRAAL.MAIN !
! !
+--------+--------+
!
+--------------+--------------+
! !
+--------+--------+ +--------+--------+
! 1.SECTION ! ! 2.SECTION !
! ! . . . ! !
+--------+--------+ +--------+--------+
! !
+-----+-----+ +-----+-----+
! ! ! !
+----+----+ +----+----+ +----+----+ +----+----+
! 1.ROOM ! ! 2.ROOM ! ! 3.ROOM ! ! 4.ROOM !
! ! ! ! . . . ! ! ! !
+---------+ +---------+ +---------+ +---------+
There may be any number of .section files beneath the graal.main
file, and any number of .room files under each .section file.
(Although placed in the middle of the structure, the importance of
section files vary greatly depending on the design of your adventure.
In some cases, you may want to have only the one section file,
containing nothing at all! More about this further on.)
In all these script files there are three basic kinds of lines:
Comment lines - All comment lines must begin with the characters
/*
which can be followed by any text, like in
/* This is a comment if ever I saw one!
Use comments a lot, because the GRAAL syntax is not particularly
reader-friendly, and what was clear in your mind when you typed it in
may seem like pointless rubbish a couple of weeks later - if you don't
have the comments there to remind you.
Empty lines - may be used as separators for improved readability.
Statement lines - each statement line contains a statement (or
keyword, if you will), followed by a colon, and one or more
parameters separated by semicolons. Like this:
statement: parameter1;parameter2;...;parameterN
In many cases, the parameters contained in a keyword line are
conditions or commands, containing their own parameters. Example:
ACTION: 4;IFRF 2=0;SAY I Can't do that;EXIT
In this example, ACTION is a statement that comes into play when
GRAAL is checking a command input by the player. More precisely, the
ACTION statement in this example will be used if a sentence using
verb 4 (parameter 1) has been entered by the player. GRAAL will then
execute the commands SAY and EXIT, but only if the condition
IFRF 2=0 has been fulfilled first.
Note: There must be a space between the ":" and the parameters, but
there must be no spaces around the semicolons separating the
parameters! Also, there is no semi-colon after the last parameter in
a line.
Each statement in a script file may be up to 255 characters long.
The script files are case sensitive, so make sure all keywords are
written in upper case.
Any line in the three types of script files mentioned above that does
not conform to the rules will be spotted by GRAAL at run-time, normally
causing the execution of the adventure to halt with an error message.
Double-check everything, and use the GRAAL editor for help with the
parameter syntax and syntax checking!
2.5 THE GRAAL.MAIN FILE
-----------------------
"All right, but what do these different script files actually do?" I
hear you scream.
Good questions! The first, and in many ways the most important, is
the graal.main file. It is called that because that is what it must
be called - if GRAAL doesn't find a graal.main file in the current
directory, it will say so and terminate.
The graal.main file sets up everything that is common to the entire
adventure, such as:
* All basic aspects of the main character's behaviour - he's
certainly going to be around in the entire adventure!
* Where the adventure starts.
* The fonts to be used for the user interface.
* All the objects that can be carried anywhere in the game.
* All the characters involved in dialogues.
* All the actions The main character can take that are common to all,
or at least to most, locations.
2.6 THE .ROOM FILES
-------------------
Once GRAAL has interpreted the graal.main file, it knows which room
file to look for first. All room files have the suffix .room
preceded by the room number, so the first room file used in the
adventure is very often called 1.room . (If you decide on a better
starting point for the adventure later on, you may of course tell
GRAAL to start in, for example, room 45 instead.)
Since GRAAL reserves memory for each possible room number from 1 and
up to the highest room number used, it is quite wasteful to have
"gaps" in the room sequence. If you have deleted some rooms in the
middle of the sequence, use the vacant numbers when you add new
rooms, thus minimising the gaps in the numbering sequence.
The .room files do much the same for each adventure location or
"room" as the graal.main file does for the adventure as a whole.
They contain, among other things, the following:
* The name of the IFF file to be used as the background in the
Scene Area.
* Information about "clip-art" to be loaded in and used as graphic
elements and objects for this particular room.
* The dialogues that take place in this room.
* The objects that can only exist within this room.
* All actions that are specific to this room.
2.7 THE .SECTION FILES
----------------------
.section files are very similar to .room files. Their main purpose
in life is to make GRAAL more memory efficient. The basic idea is
that many graphic adventures are divided into logical sections, a
section being a number of connected rooms where the same objects can
be handled and a number of puzzles need to be solved before you can
move on to the next section. However, once you are through with a
section, there are a number of objects and images you will never use
again, and therefore they can be deleted from memory the freed space
can be used for the objects of the new section. Or, perhaps the
rooms of the section share a lot of graphics - like a labyrinth in a
system of caves probably would.
How you define sections is up to you, and you do not need to use the
concept at all if it is irrelevant. (In that case, just use section
1 for all the rooms, and place no commands in the 1.SECT file - just
a few comment lines describing what the blazes you are up to, with a
couple of totally blank lines in between.)
2.8 THE .SCENE FILES
--------------------
.scene files are known as cut-scene files, containing non-
interactive parts of the adventure (playing much like cartoon
movies). They can also be used as subroutines, saving you the
work of re-coding the same set of commands in a lot of places.
The cut-scene files are a little special (but simpler) than the
previous script files, and will be discussed later on.
2.9 THE .PTRN FILES
-------------------
.ptrn files are not scripts as such - they contain definitions of
animation patterns that would be too long to enter into the other
script files directly, or you wish to re-use in a number of
different places in your scripts - or all of the above. (For those
of you familiar with Amos Pro, the contents of the PTRN files follow
the AMAL syntax exactly.)
2.10 RUNNING AN ADVENTURE
-------------------------
At some point or other, you feel that the script files are ripe for
testing. This is simply a matter of trying to start the adventure by
running GRAAL_2, which must be placed in the same directory as all
the script and graphics files you refer to in the game.
(You should, of course, run the syntax checker in the GRAAL_Editor
on all scripts first to get rid of all typing errors and other such
mistakes. This takes far less time than re-running GRAAL_2!)
First, the GRAAL_2 program loads. Then, the GRAAL title screen is shown.
The progress indicator (the horizontal bar) indicates that the contents
of the graal.main file are being loaded and processed. When the title
screen disappears and the screen goes blank for a moment, the system is
working on the first .room script.
Most likely, you will get some error messages before everything starts
running smoothly. A GRAAL "run-time error" message will appear in yellow
text surrounded by a red border on screen, stating the type of error, which
room was currently loaded, and which file was last accessed. Note: This
file may in some cases not be the actual culprit! For example, If GRAAL
has loaded a small cutscene file, executed it and run into a problem in
the calling script later on, it is still the name of the completely
innocent cutscene file that is shown, so take this information for what
it is.
Some problems may be of a less severe nature. In those cases, GRAAL
sometimes lets you decide whether to continue playing, or exit the
program (in which case it tries to clean up the memory just as if you
give the "Q"uit command when playing the game the normal way).
Continuing after such a warning is not always safe: The error almost
certainly affects some aspect of the game. However, things like flag
value errors may often be corrected using the on-line monitor (see the
appendices).
Also note that in the error messages, the offensive statements and commands
are sometimes printed in a slighlty different way from how they appear
in the script: All RBOBn, SBOBn, ROBJn and SOBJn statements are "translated"
to show a numeric BOB image or object number. So if your N_xxxxBOBS
statement in the graal.main file decide that ROOMBOBS start at image number
51, an erroneous statement containing RBOB4 would actually show up as
the number "54" in the error message. (Sorry 'bout that. Read on, and
perhaps you will understand what the heck I am talking about later.)
There will most likely always be some errors that are not trapped properly,
and the system may just "die on you". In those cases, try to determine how
far the loading process has actually gone, and check the structure of YOUR
scripts carefully against the Olaf 1 demo and the order in which things
appear there! Also, resetting your Amiga before trying again often helps.
For an overview of the features of the GRAALplayer interface, read the
"Olaf.guide" that contains instructions for the demo adventure.
Enough of this already. Ready to start on an adventure?
3 STARTING ON AN ADVENTURE
==========================
I won't bother you with a lot of talk about how you must plan the
contents of your adventure, have a good storyline, and so on and so
forth. If you don't that's not my fault, is it? I simply assume you
HAVE a story to tell, and that you are well aware of how graphic
adventures of this kind works - if you don't, you'd better play some
first. I will then show how you can do it all using GRAAL.
I won't even go into the basic idea behind my example adventure "Olaf
Longhair", because surely you have played the demo by now!
This tutorial concentrates on everything that makes the first four
rooms in Olaf Longhair tick - because once we have that much going,
almost everything follows along the same lines (or will be pointed
out separately).
The four rooms, in order of appearance, are:
1. The bar, where Olaf wakes up the morning after the night before,
and has an informative chat with the bartender.
2. The street outside the bar, where he bumps into a strange-
looking guy with an even stranger-looking animal.
3. The harbour, where he meets a foreign captain and deals with a
rather irritating seagull.
4. The shopping emporium of one Ali Harrod, Esq.
3.1 STARTING ON THE GRAAL.MAIN FILE
-----------------------------------
Look at the graal.main file now.
One of the best ways to start out is to take a graal.main file that
actually works, and alter it to suit your own needs. Using the GRAAL
editor, you can also choose to create a graal.main file template,
with comments and statements showing what is mandatory and what is not.
(This method can laso be used for the other script types.)
Here are some statements that can be set almost immediately. The other
ones will be dealt with once we start designing rooms, objects and
characters for the adventure.
NAME: "Olaf Longhair - GRAAL Demo Version"
The name of my adventure is "Olaf Longhair Goes East". (The quotes
are not there because they enclose a string or anything - I actually
want them displayed on screen when the name of the adventure is
called up by pressing the [V] key during a game!)
VERSION: ...
The adventure version number. This is especially useful to guarantee
that you don't try to load old saved game files when testing a newer
version of the adventure.
Then follows a lot of statements dealing with the player interface
layout, and numbers setting limits for how many images, objects, and
other things GRAAL can handle in your adventure. Read the comments in
the graal.main file, that's the best way to learn about them. Also,
each statement is thoroughly described in the "GRAAL.guide" on-line
reference.
At this point, we will not get much further without bringing the big
star, our main character, the man, Olaf Longhair himself, into play!
3.2 THE HERO - WHAT A CHARACTER!
--------------------------------
One of the things GRAAL makes so easy to manage is the point and
click control of the main character - in this case, Olaf.
GRAAL controls what animation sequence is the correct one to use in all
standard situations, in which direction Olaf is heading, where in a
room he can actually place his feet, and so on.
Wonderful as all this may be, it doesn't relieve you of the responsibility
for the character design - in other words, before GRAAL can do all this
wonderful stuff, you must design the main character and the animations
used for his basic movements.
Basically, what we need now are some still images and animation cels
showing Olaf in various standardised poses. For "Olaf", all these are
placed in the IFF picture file "Olaf_Original.iff", which you should
take a look at now.
What the images portray are:
* Olaf walking towards, away, and sideways
* Olaf's front, back, and profile when standing still
* Olaf talking - the front, back, and profile views.
* Olaf manipulating things - also front, back and sideways views,
but for each view also in three "height" versions - for objects
high up, far down, or "in mid-air".
As you notice, the images of Olaf in the file are neatly and evenly
spaced. This makes it easier for GRAAL to "cut out" these images and
store them in its image bank later.
Also note that there are no separate images for the right and left
profiles - to make life a little easier, and less memory consuming,
the profile images will simply be flipped by GRAAL when a reversed
view is required.
We will need more images of Olaf during the course of the game, but
since they will only be used for special occasions, they are loaded
into memory only when they are needed and erased afterwards. So
"Olaf_Original.iff" contains all the "global" images of our main
character and favourite hero.
3.3 BASICS ABOUT IMAGES AND BOBS
--------------------------------
We are going to talk a lot about stills, cels, animations and BOBs
in this tutorial, all concepts dealing with how an image is used.
A still is any image that is static.
An animation is any image that moves, and it does so by using a
number of slightly different stills replacing each other, called
ANIMATION CELS.
BOB is short for Blitter OBject. BOBs are well-known to Amos
programmers. They are, basically, the way GRAAL displays all
graphics on screen that aren't just backdrops: Objects, animated
characters, texts, and so on. BOBs can be put into the display and
deleted again without harming the backdrop picture. To achieve this,
the system must keep track of all the little graphic bits and pieces
by assigning each one used at any time with a BOB number. To make it
easier to keep track of the images used by the BOBs, they are stored
in a BOB image bank.
Any BOB may use any image (or vice versa, depending on how you look
at the world). For example, BOB number 44 may be used to display a
flower, held in image bank position 56, in one scene. In another
room or scene, the same BOB number 44 may be used to display a
knife, which is image 78 in the bank. Confusing? Just keep this in
the back of your head until we start discussing the script file
statements!
Since re-cycling is the word of the day, there is no difference in
the image types used for different purposes - all are stored in the
BOB image bank, and you may use the same image as an animation cel
in one situation and as a still image in another.
The BOB bank where we store all images, must be logically divided
into four sections:
1. BOB images for system use occupy slots 1-10. This reserved area
is not really necessary anymore - all user interface graphics
can be stored in any global BOB position - but it's kind of a
left-over from previous versions. (The only thing it REALLY means
that you actually have 10 more global bobs that you actually
specify with the N_GLOBALBOBS: statement. However, if you want
to keep things neat and tidy, I recommend you use 1-10 only for
"system graphics", and store "game graphics" in... see below...)
2. Global BOB images are those that are kept in memory at all
times, for example all Olaf's basic movements. The number of
slots used for these are defined with the N_GLOBALBOBS: statement.
11 is always the starting number for this range. Make an
educated guess how many of these you'll need. "Olaf" uses about
40, which translates to images 11 to 50.
3. Room BOB images are images that are only needed in a specific
room - as soon as the game switched to a new room, all these
images are erased from memory and replaced by the graphics for
the new room. The number of these is defined by the N_ROOMBOBS:
statement. When referred to in the scripts, their numbers are
always prefixed with RBOB: RBOB5 means room BOB 5
4. Section BOB images work the same way as room BOBs, but for a
section (collection of connected rooms) rather than a single
room. Their number is defined by the N_SECTIONBOBS: statement.
When referred to in the scripts, their numbers are always prefixed
with SBOB: SBOB10 means section BOB 10.
If you make a mistake when estimating the number of each image
category here, it is not the end of the world. The definitions can
be altered at any time later on.
3.4 THE IMAGES IN THE GRAAL.MAIN FILE
-------------------------------------
Back to the graal.main file now, to practice what was just preached:
N_GLOBALBOBS: 40
N_SECTIONBOBS: 30
N_ROOMBOBS: 70
This means that right now, we believe we need 40 global BOB images,
30 for use in sections, and 70 for use in rooms. If we change our
minds later on, we can always change the numbers then.
Let's define the main character's images. The statement
CLPART: Olaf_Original.iff
tells GRAAL that following statements will grab images from the
picture file Olaf_Original.iff
BOBS: 10;11;1;1;31;47;32;0
tells GRAAL to grab 10 BOB images and store them in image slot 11
and upwards (slots 1-10 are reserved for system use, remember?)
More BOBS and CLPART statements follow upon this first one, until
all basic images we need have been stored in the image bank.
Now the images we need for Olaf's basic behaviour is in the image
bank, which means we can tell GRAAL a little about their basic
properties and how they should be used.
CHARACTER_HEIGHT: 40
CHARACTER_WIDTH: 22
are two statement stating Olaf's approximate and average height and
width. These values are used to position Olaf properly on the
background in relation to walls, and also to place the text
representing Olaf's speech at a proper distance above his head.
CHARACTER_COL: 9
Olaf's speech will be shown as text with colour no. 9. Use a rather
bright colour, which along with the automatically added black border
around the text should make it readable enough.
STILL_RIGHT: 14
STILL_LEFT: $800E
STILL_BACK: 12
STILL_FRONT: 11
These statements tell which still images are to be shown when Olaf
is facing in the respective direction, doing nothing.
But wait a minute: What is that strange BOB image $800E? Oh, that's
quite simple, at least according to the very special logic of AMOS
Pro syntax: It is simply image 14, flipped over so that it faces
left instead of right! The "$" indicates that this is a hexadecimal
number. Well, "E" is 14 in hexadecimal, and the Amos Pro way of
flipping BOBs is to add hex 8000 to the image number! Thus, 14,
flipped over, is $800E!
(This strange remnant of Amos syntax may be eliminated in coming
versions of GRAAL - then again, it may not. It would slow execution
down if I altered it.)
Anyway, on with it.
PAUSE_RIGHT: 13
PAUSE_LEFT: $800D
PAUSE_BACK: 12
PAUSE_FRONT: 11
These images are used when Olaf pauses after having gone in a
certain direction. If you wish, they may be set to exactly the same
values as the STILL_ images. However, as you see, Olaf uses image
13, a slightly more relaxed, forward-facing and "ready-for-input"
pose, for the right and left poses in these statements than in the
STILL_ statements.
(You don't HAVE to make the left pose the flipped-over version of
the right pose - if you want to draw different images for each
direction, go right ahead. But I'm too lazy!)
WALK_RIGHT: A 0,(16,6)(15,6)(14,6)(17,6)(18,6)(17,6) ...
WALK_LEFT: A 0,($8010,6)($800F,6)($800E,6)($8011,6) ...
WALK_AWAY: A 0,(29,8)(30,8)(31,8)(30,8)
WALK_TOWARD: A 0,(26,8)(27,8)(28,8)(27,8)
So far, all we have done is to specify still images. Now we enter
into the gruelsome, yet strangely attractive world of animation! And
yes, AMOS Pro users will immediately give a cry of joy: It's AMAL!
AMAL is AMOS Pro's animation language, and yes, GRAAL uses the same
syntax for animations. So let's see what we've got here:
"A 0," simply tells GRAAL to repeat the following animation sequence
indefinitely. (Stay calm - GRAAL will handle all starting and
stopping of standard character animations automatically.)
"(16,6)(15,6)(14,6)" and so on are the images and display lengths of
each animation cel. For WALK_RIGHT, first image 16 is displayed for
6 frames (=screen updates), then image 15 is displayed for 6 frames,
and so on. When the end of the list is reached, the animation loops
and starts over with image 16 again. As you see in the WALK_LEFT
statements, flipped images are used in animations also - no
problems.
It's quite wise to use 6 frames as the smallest time space for any
image during background scrolling - 3 is possible and may work well
if you have a limited number of BOBs in each scene in your adventure.
However, if you paint on a large canvas so to speak, the system will
have problems fitting all graphic updates into a 3 frame space and so
the animation may become jerky. (6 isn't safe in all situations, but
it usually works and is a good compromise.)
WALK_SPEED: 1.2
This statement just adjusts the speed with which the character
walks. Especially when walking sideways, you wish it to look like it
is the character's feet that actually propel him across the floor -
watch some really bad cartoons, and you will spot how the characters
"glide" across the floor as if it was made of ice! The proper value
here depends on how large steps your character takes in your
animations. Do a little experimenting!
TALK_MAP: 11;A 0,(20,18)(11,12)(20,12)(11,6)(19,12)
Not only walking is animated and automated in GRAAL - talking is as
well. The animation to be used for speech in each situation is not
connected to a certain direction, but rather to what image is
displayed on screen at the time the character starts talking - The
above statement tells us to use this animation if the character is
facing forwards (image 11) when the speech starts. As you see in
graal.main, there are six TALK_MAP:s specified - all STILL_ and
PAUSE_ images are accounted for, which indeed they must be for GRAAL
automation of the speech to work in all standard situations. Up to
eight TALK_MAP:s may be specified in all.
HANDLE_MAP: 11;A 1,(11,12)(36,1);A 1,(11,12)(34,1);A 1,(11,12)(35,1)
Standard "manipulation" or handling of objects are specified in a
similar manner - the animation to be used when a certain object is
handled depends on a) the previous character image on screen and b)
whether the object in question is placed high up, low down or in
mid-air - an animation sequence for each possible position is
supplied in the same statement, separated by semicolons.
Note that the last image in each sequence should be specified as
shown for only ONE frame - this is because a) the character will
stay in that position during the handling of the object anyway, and
b) we wish to immediately do some other graphic tricks after the
HANDLE command has been given, such as placing an object in the
character's out-stretched hand. Specifying too long a pause in these
animation sequences would produce an unwanted pause in the flow of
the script.
To summarise, if the character is facing forward using image 11, and
suddenly is commanded to handle an object placed in mid-air, (the
cup in the "Constantinoplian" bar is a concrete example), the middle
animation sequence in the above statement, which is "A
1,(11,12)(34,1)", would be executed.
OK. That was a lot of hard work and tricky definitions to sink one's
teeth into, but guess what? We're done! We have actually completed a
large percentage of the animations needed for our hero, and can get
on with designing the adventure proper!
The statements we have defined above will be used and executed time
and time again throughout the adventure, and in a fully automated
fashion, too. But you control-freaks should not worry too much:
GRAAL contains enough script commands to enable you to break away
from the standard poses and animations in any given special
situation - if you are willing to take on the extra work and extra
coding in the scripts that is required.
4 "A ROOM! A ROOM! A KINGDOM FOR A ROOM!"
=========================================
As you may gather from the heading of this chapter, we now quite
badly need a room or other location to move about in - having our
hero confined to a lot of abstract image and animation statements in
the graal.main file will not make anyone happy.
Let's start with room number one. That's logical, because we have
already stated in the graal.main file that the adventure will start
there, remember? And this adventure starts in the bar, so room 1
will be "The Last Bar in Constantinople".
Similar to how the main properties of the adventure is defined in
graal.main, the properties of room 1 is defined in the file 1.room.
Have a look.
The first statement we come across here is
UPDATE: 3
which sets the updating speed of the scene area. The higher the
number, the slower the screen updating, and the more graphics GRAAL
is capable to shift between updates. To keep animations etc. from
becoming jerky, the number must be set high enough to cope with all
graphics.
Actually, this only becomes a real problem when the background is
scrolling, so the number set here is only used during such scrolls.
At all other times, the update rate is 3. And in this room, the
whole thing is completely irrelevant, because the scene fits into
the display without scrolling - it is exactly 320 pixels wide. For
other rooms, like the harbour, UPDATE: is set to 6. (I have designed
all of "Olaf":s animations to work with the update range set in
multiples of 3.)
Next, there comes a
SECTION: 1
statement, indicating that this room is part of section 1, as are
all the rooms making up Constantinople in this game.
Next, we need a background picture for the scene area. I prepared
the interior of this rather primitive bar in the file "1BG.IFF"
using the 3D modelling and rendering freeware program POV-RAY. The
gorgeous 24-bit image that was the result was then reduced to 16
colours, creating an image that is crude but suitably "cartoon-like"
for the purpose.
The background's 16 colour registers went into colour numbers 16-31
in the 32-colour palette, and the 16 standard colours used for Olaf
and any other common BOBs and images were copied into the palette in
places 0-15 (see the Master Classes for more info on handling
colours). The background file is defined with the
BG_IFF: 1BG.IFF
statement.
In GRAAL version 1, the height of the background iff:s must be 120,
but the width may be from 320 up to 640, making for excellent
scrolling background scenarios (as shown in the Constantinople
main street and the Baghdad panorama, for instance)..
Each time we enter a new room, Olaf must have a starting position
and pose. This is defined by the
START_POS: 1;13;20;115;L;1
statement. This not only indicates where Olaf starts, but whether
the background screen starts scrolled to the far left, far right or
the middle. (In this case, it's all the same, since the scene fits
within the screen width.)
Any number of starting positions may be defined for the same room -
great for those really awkward labyrinths!
GRAAL is not truly 3D - nothing shown on a computer screen ever is -
but uses a simulated 3D persective. The bar in 1BG.IFF has a floor,
extending from the very bottom of the scene area and a few lines up
in the picture - if Olaf moves higher up in the picture, he is also
going further back in the room. (The effect is demonstrated more
fully by the alley in the street outside the bar, which Olaf can
actually "walk into".)
Now, in order for Olaf to stay on the floor and not start climbing
the walls of the bar, we need some way of restricting his
movement. We do that using statements like
FLOOR: 1;16;113;304;119;1-1/2-2/3-3/4-4
Each such statement defines a rectangular part of the picture where
Olaf may place his feet. If there is more than one such rectangle,
each is defined by a separate floor statement, and all floors must
overlap with at least one other floor to enable Olaf to find his way
from one floor to another. The last parameters, "1-1/2-2", describe
how Olaf navigates between the two floors in this room. See the the
FLOOR statement in the on-line reference for more information about
this.
It wouldn't be much fun to have an adventure take place in only one
room (although such a thing IS possible - how about a "closed room
murder mystery"?). So the next statement,
EXIT: 1;5;60;12;119;10;116;Exit to\street
defines an exit from the bar. This creates a "clickable" rectangle
on the screen with some additional parameters describing the
properties of the exit. We will come back to the subject of
switching rooms further on.
So, now we have a background, an exit, and area to move about on,
and much more. Time to add some special graphics to the room to
spice things up a little.
CLPART: 1FG.IFF
is a statement telling GRAAL that we wish to grab some clipart from
the 1FG.IFF file to use as images in this room. The
ROOMBOBS: ...
statements that comes next follow the syntax of the BOBS: statement
we used in the graal.main file. Every image grabbed with this
statement should later be referred to by a "room BOB image number",
which is a number proceeded by "RBOB". For example, RBOB3 means room
BOB image 3.
The images we grab as RBOBs are all used for objects and graphics
that are unique to this room, and are not much use outside it
(although you CAN grab clipart from the same 1FG.IFF file anywhere
you like in the game, of course).
Perhaps some of the clipart we just loaded is supposed to be pasted
into the scene without doing anything except being pretty. The
statements STATIC: and ANIM: are used for this purpose - which one
depends on whether the image should be static or animated. We have
two such static objects in the bar. One is the barrel behind which
Olaf appears. It has no other function except hiding Olaf at the
start of the game and being a general foreground object which adds
a bit of depth to the scene. The other is the wooden pillar, also
placed in the foreground.
That is the graphics department of room 1 over and done with.
5 THE OBJECT MATTER
===================
You could, theoretically, spring Olaf loose in the bar now, but
there would be absolutely nothing to do - just an exit pointing to
an undefined room, floors to move about on - and a barrel to hide
behind! So far, there is not a single object to interact with!
Just as with BOB images, objects are defined in various places
depending on where in the adventure they may appear - just in one
room, in a section, or in the entire adventure. Sticking with the
1.room file for the moment, you see some
ROOMOBJ: ...
statements here. They define objects which are never removed from
the bar, and never changed in any way: One of the barrels, the plate
of spam that Olaf refuses to touch, and so on. Room objects are a
great way of adding atmosphere, detail, and red herrings to a game
without wasting computer memory - from the players' point of view,
there is no way of telling whether an object is a room, section, or
global object. Only you know!
The policy in the tutorial is to leave details to the on-line
reference, but understanding the properties of an object is rather
vital, so we will examine one of the global objects present in the
bar closely. (The room objects are no good for this purpose, since
their use is severely restricted - they can't be picked, up,
altered, or anything like that!).
In the graal.main file, locate the line
OBJECT: 16;piece of\paper;8;-1;56;RBOB6;60;119;14;0;$800E;with;-1;0;
8;47;LOW;WD;an;this;it
This statement describe the sheep bones on the left barrel in the
bar, and in some detail! Let's take it parameter by parameter:
16;
means this is global object number 16.
piece of\paper;
is the name of the object. The backslash is replaced by a backslash
when the name is shown in the scene area.
8;
is the room where the object first appears
VIS;
means the object can be seen and handled. (NVIS means "invisible".)
56;
is the BOB number (not the IMAGE number!) that will be used when
displaying the object.
RBOB6;
is the BOB image number which is used to display the object by
default. This could also be an animation sequence using the same
animation syntax as the TALK_MAP: etc. statements explained
previously.
But wait a minute! We use an RBOB image, obviously grabbed in the
8.room file, to display a global object, which is obviously not tied
to that one room? Isn't this strange?
No, it actually makes sense. Room 8 is the only place where the
piece of paper will actually be SHOWN in that shape - when it is
used further on in the game, it will only be displayed using
its inventory icon. So this is a safe use of RBOBs!
60;119;
is the x and y position of the RBOBs hotspot.
14;0;
is the "character offset". When Olaf wants to handle the piece
of paper, he will walk to a position 14 pixels to the right and 0
pixels above the object's hotspot.
$800E;
is the still image used to display Olaf once he has walked up to the
object. Since the object is to the left of him, he will face it using
image $800E. And specifying the correct still image for each object is
vital: Should Olaf begin to handle the object after walking up to
it, the HANDLE_MAP sequence linked to image $800E will be used. Should
he start to talk, the TALK_MAP sequence linked to the image will be
used. But you need not worry about this, as long as you specify the
HANDLE_MAPs, TALK_MAPs and still images used for object handling
correctly!
with;
is a preposition. If a preposition exists, it is assumed that this
object can not be USEd on its own - it must be combined with
something else, and so the sentence line will read USE PIECE OF
PAPER WITH, and the system will wait for a second object to be clicked.
If this parameter is left blank, the object will be used on its own.
PICK;
indicates that the object can be picked up (the condition IFPICK returns
TRUE). NPICK is used for the opposite.
Actually, you can easily override this parameter using script
commands - picking upp objects marked NPICK, and making the character
refuse to pick up objects marked PICK. Still, this setting means objects
which rely on the global ACTION: statements dealing with picking up and
dropping handles the object in the right way.
Also, there is no risk in making an object pickable even if it is
initially invisible (NVIS). If it cannot be seen, it cannot be accessed
by the player, and thus, the PICK status becomes insignificant...
(This should ALWAYS be NPICK for room objects, unless you make
sure you make the character drop the object again before he leaves
the room!)
0;
If the object is animated using an animation command (instead of the
single RBOB17 for this example), the animation channel must be
specified here. The range of possible values is 2-16, and as with
BOB numbers, the same number may not be used for two things
simultaneously. The piece of paper is not animated, and therefore this
parameter is 0.
8;
This is the object's "quick command", that is, the command issued when
the player points to the objects and clicks the right mouse button.
Verb 8 is LOOK AT.
47;
This is the object icon used to show the object in the inventory:
Global BOB image 47.
LOW;
This is an important one for all objects which can be picked or
handled! It determines which of the "handle animations" Olaf will
use. Since the piece of paper is on the floor, the LOW animation
will be used. (Always place objects, or Olaf, using the character
offset co-ordinates so that one of the three positions can be used
in a natural way!)
DW;
This is an "attribute string" which can be used to determine some
general properties for the object. "D" stands for dead object, and
"W" for "wood". (A rather pointless attribute in this case. Basically,
it only tells us that it is softer then stone or steel!)
Attributes are used to make basic responses to some actions seem more
natural - you don't have to define separate replies to all objects,
but can specify a general response for all cases of Olaf trying to
use the small knife on objects made of wood, for instance. You may
also find an "abstract" class very useful - when Olaf attempts to
pick up the horizon, it enables you to respond with some really
insulting remarks!
You should remember that GRAAL is quite flexible in many ways, one
being that there exists GRAAL commands to alter many of the object's
properties, such as the name, visibility, location and so forth at
any time during the game. See the on-line reference for a complete
list of commands. Generally speaking, the statements in the script
files set things up - it is the commands contained in DACT, LACT and
ACTION statements executed during gameplay that brings the whole
thing to life!
While we are at it, let us examine another, but more human, global
object: The bearded man / bartender.
Characters which are involved in dialogues must always be specified
as global objects. The bartender, starting out as the "bearded man",
is one example. So, what is the difference between a bearded man and
some sheep bones? Well, the bartender is animated using a default
animation sequence, as you see. This sequence also uses RBOBs, since
the bartender never leaves 1.room. Furthermore, the bartender can
not be picked up (there's a relief!) and uses animation channel
number 8 for the animation. His special attributes are "MV" -
meaning he's a male character and alive.
6 SECTION OBJECTS AND BOBS
==========================
There are a third class of objects involved in the bar scene, those
defined in the section file 1.section with the SECTIONOBJ:
statements. These are objects that only exist the very first time a
new section of the game is visited, and disappears again before the
section is exited. It is not that useful, but some of the objects in
Constantinople is of this kind - the magic flute, for example, which
disappears into the pawn shop before you can leave town.
You will probably find section BOB images (SBOBs) more useful than
section objects. These are grabbed in the section file the same way
RBOBs are grabbed in the room files, but with the SECTIONBOBS:
statement. Needless to say, they remain in memory during the visit
to the section, but disappear and are replaced by other graphics the
moment you walk into another game section.
You are not obliged to use the section concept at all, especially if
your adventure is quite small. However, you must have at least one
section file in your adventure, even if it just contains a comment
saying "Not Used". Then specify all your rooms as belonging to this
"empty" section.
Okay, we have everything in place, except one VERY important thing -
the instructions telling Olaf to deal with the commands you give
him!
7 (LIGHTS! CAMERA! ACTION!)
===========================
We now have the lights and the camera, so to speak. But precious
little action. (Well, the lights aren't actually turned on yet. That
is done with a LIGHTS ON command, explained further on!)
All conditions and commands used to respond to the player's actions
are placed in ACTION: statements (leaving the dialogues out of it
for the moment).
ACTION: statements may appear in all three major types of script
file: .room, .section and graal.main.
The idea is that the ACTION: statements taking care of a certain
action is placed closest to the place where the action takes place.
If an action can only take place in one specific room, the ACTION:
statements for it are placed in that .room file. If the action is
only valid in a certain section, they are placed in the .section
file. If it is something that needs to be taken care of regardless
of where it appears, the graal.main file is the place.
In fact, almost every action should have some "safety net" in the
graal.main file - if no specific action is taken in the ACTION
statements of the .room and .section files, the graal.main ACTION:
statements should at least make it look like Olaf understood what
you were trying to do! There is nothing more unrewarding than
clicking away on lots of things and have absolutely nothing happen.
Okay. So we write a lot of action statements containing commands
that makes Olaf walk, talk, and jump! But how does GRAAL know when
to use what actions?
Well, suppose we want to pick up the cup on the barrel. Let's look
at how that is performed in GRAAL, keeping in mind that GRAAL always
checks the .room file first, then the .section file, and finally, if
nothing else helps, the graal.main file! Each file is checked from
the top down to the bottom, which is very important to remember in
order to get the sequence of tests and commands right.
When the player has clicked PICK UP and the CUP, GRAAL starts
looking for appropriate ACTION: statements, knowing the number of
the verb (PICK UP = 2) and the object (the CUP is section object 3,
referred to as SOBJ3).
The first parameter in each ACTION: statement is always the verb
number, and in 1.room, the first ACTION: 2;... statement that we
come across is
ACTION: 2;IFOBJ 1;....
"IFOBJ 1" is a condition telling us that the rest of this ACTION
should only be executed if our object was number 1. It wasn't - it
was SOBJ1 - so we continue to the next statement.
ACTION: 2;IFOBJ ROBJ1;....
No luck here, either. We weren't after the plate of spam, known as
ROBJ1, so we continue, and quickly find that there are no more
ACTION:s for verb 2 in the room file.
Switching to the 1.section file, let's see if we are more lucky. No,
not a single PICK UP command, actually. This is not so surprising,
since almost all objects start out in a certain room.
Well, why then wasn't there a command to handle the cup in the
1.room file? Because, with the power of GRAAL, almost all PICK UPs
of any "pickable" object can be handled using a few single lines in
the graal.main file - the two objects especially handled in the
1.room file were there because they are handled a little differently
from most of the rest. Going on to the graal.main file then, we find
the following:
ACTION: 2;IFCARR;SAY I Already have it!;EXIT
IFCARR says that if the object we refer to is already in the
inventory, then let Olaf say "I already have it!". EXIT means no
more tests on ACTION statements will be done for our current
input: The sentence line will be cleared and Olaf is ready to try
something else.
However, SOBJ1 is NOT in our inventory yet, so we go on:
ACTION: 2;IFPICK;MOBJ;HANDLE;W 12;PICK;HANDLE -1;EXIT
Now behold the true power of the GRAAL. This is the stuff we have
been tormenting ourselves for all along the tutorial up to this
point!
IFPICK;
If the object is "pickable"...
MOBJ;
Olaf walks to the default offset position next to the object (as
specified in the OBJECT: statement for the cup)...
HANDLE;
Olaf stretches out a hand according to the HANDLE_MAP: animation...
W 12;
and waits for about 1/4 of a second...
PICK;
grabs the object (it disappears from the screen and enters the
inventory list)...
HANDLE -1;
lowers the hand again to the position it had before the
HANDLE command...
EXIT;
...and then we are done!
Now, if our object hadn't been "pickable", the ACTION: used by us
above are followed by a couple of "safety nets". (Remember, we never
get to these lines if the object has indeed been picked up - the
"EXIT" command sees to that.) One example of such a safety net is:
ACTION: 2;IFTYPE -;SAY That was rather far-fetched, wasn't
it?;EXIT
IFTYPE -;
This checks if the referred object was an abstract object, like the
horizon in the Constantinople harbour. Since abstract objects can't
very well be picked up under any circumstances,
SAY That was rather far-fetched, wasn't it?;EXIT
makes olaf "speak" this sentence using the talk-map corresponding to
his current position on the screen, and
And finally, if the object happens to be un-pickable, but of another
type,
ACTION: 2;SAY I can't pick that up.;EXIT
gives a rather dull but to-the-point message to the player.
Don't go erasing ACTIONs in the supplied example graal.main file
altogether the first thing you do - a lot of these "safety net"
actions should be in almost any game, although you should of course
alter the wording and detailed behaviour to suit your own needs!
8 USING EXITS
=============
Now that we are familiar with the general behaviour of ACTION
statements, it is time to explain how exits work.
As you may or may not remember, the EXIT: statement in the 1.room
file defined a "clickable" rectangle on screen. However, we never
explained what happens when the player clicks the exit.
This is what happens: GRAAL interprets this as a very special input
sentence, with the VERB set to 0 and OBJ1 set to the number of the
exit. It then checks the ACTION statements just as if the player had
input a normal command. This is a typical ACTION statement to take
care of an exit command:
ACTION: 0;IFOBJ 1;MEXIT;GOTO 2,1
0;
was the verb number indicating an "exit click".
IFOBJ 1;
tests if it was exit number 1 that was clicked.
MEXIT;
is a special command that can only be used in ACTION: 0;...
statements. It makes the main character move to the exit point
specified in the EXIT: statement (not to be confused with the EXIT
*command*, which is something completely different).
GOTO 2,1
is a command specifying which room and entrance to go to. Voilà!
Of course, you are free to do whatever you like in these statements,
just like in any other ACTION statement. You may manipulate the way
exits are interpreted to your heart's content!
9 THE DACT STATEMENTS
=====================
In each room file, there must be at least one DACT statement. The
DACT statements contain conditions and commands that are run through
each time the room is entered. The flow of control is the same as
for ACTION statements - if a condition is not met, the rest of that
DACT statement is disregarded, and if an EXIT command is
encountered, no more DACT lines will be checked this time around.
When GRAAL starts to run through the DACT statements, all graphics
and objects are already loaded into their proper places. However,
the screen is still black - the light switch has not been pushed
yet, so to speak. This means you can do tests and move things around
using commands in the DACT statements before you let the player see
the scene, which is very, very useful. Once you are done preparing
the scene, simply use a LIGHTS ON command in a DACT statement. When
an EXIT command is encountered, control is handed over to the
player.
10 HAVING A CHAT
================
There is only one major subject we have not discussed at all so far:
How to talk to other characters in the game.
In the bar where the game starts, there is a bearded bartender who
are very likely to become the first person Olaf speaks with. Let's
look at how this is done.
First of all, any character involved in conversations must be
defined as an object using an OBJECT statement in the graal.main
file. There is nothing special with the definition: Just make sure
the object cannot be picked up, visible, and placed in the room
where the dialogue takes place. Also, assign an animation channel to
it.
Each dialogue has its own unique number, and is defined by a
DLG statement in the graal.main file (below the OBJECT statements).
The bearded man/bartender dialogue is dialogue number 1, and this
is the DLG statement:
DLG: 1;5;11;-20;A 0,(RBOB4,12)(RBOB6,24)...
1;
means this is dialogue number one.
5;
means that the object Olaf talks to is global object 5 (the
bartender).
11;
is the colour used for the text displayed when the bartender speaks.
-20;
determines how far above the bartender's head the text is displayed.
A 0,(RBOB4,12)(RBOB6,24)....
is the animation used when the bartender talks.
Now that we have two statements in the graal.main file, we move on
to the 1.room file, where the actual dialogue contents are defined.
A dialogue always starts when GRAAL encounters a DSET command in an
ACTION or DACT statement. It then shifts into another mode, where
the player's input is no longer a normal command sentence, but only
the number of a dialogue alternative. GRAAL responds to the chosen
alternative by going through LACT statements that correspond to the
selected alternative, and does not consider the ordinary ACTION
statements. Sooner or later, GRAAL encounters an EDLG command in one
of the LACT statements, which terminates the dialogue and switches
the game back to the normal input mode.
Let's begin from the beginning. When the player commands TALK TO
BEARDED MAN, the following ACTION line is performed:
ACTION: 5;IFOBJ 5;IFOF 1=0;MOBJ;SAY Hello;RESP R,1,Hello,yourself;
DSET 1,+3,+7,+9,+11;EXIT
5;
the verb is TALK TO - we have a match
IFOBJ 5;
the object is the BEARDED MAN/BARTENDER - we still have a match
IFOF 1=0;
Hello, what's this? It's a test of an object flag, a concept we have
not discussed earlier. Object flags are variables attached to each
object. There are six flags for each object, and each can have any
numerical, integer value. By assigning values to flags and testing
them, you can keep track of everything that has happened to an
object - it's up to you to decide what to use the flags for. In this
case, I have decided to use flag 1 for the bartender to see if this
is the first time ever we talk to him. All flags are initially 0, so
this test - IFOF 1=0 - is true in our case. Before the dialogue is
ended, the flag values will be set to 1 to indicate that next time
around, we should resume the conversation in a slightly different
manner.
OK, on with it:
MOBJ;
We move up to the bartender just like we move up to any object
before manipulating it.
SAY Hello;
Say "Hello".
RESP R,1,Hello, yourself.;
This is the bartender's response. "1" means GRAAL will look up the
statement DLG: 1;... in the graal.main file to find out how the
bartender behaves when talking. "R" means the default bartender
animation will resume as soon as the talking is over.
So far, all statements have been performed with the game still in
the "normal" mode. Now comes the command which switches to dialogue
mode:
DSET 1,+3,+7,+9,+11;
This command engages us in dialogue number one and tells GRAAL to
add the four dialogue alternatives 3, 7, 9, and 11 to the list of
possible lines for Olaf to speak. Since this is the first DSET
statement ever to be performed for dialogue one, they will be the
ONLY four alternatives.
EXIT
exits the parsing of the TALK TO command, and leaves us to get on
with the dialogue - the player now has to select a dialogue line
from the dialogue area which has replaced the normal control area.
Hmm. Dialogue lines 3,7,9, and 11. What are they? All the lines are
defined by LINE statements in the 1.room file. Let us take line 3 as
an example:
LINE: 1;3;What is this place?;Where did you say I was?;
1;3;
means this is line 3 of dialogue 1
What is this place?;
This is the line appearing in the dialogue command area (where the
player can choose a line to say) when the alternative is previously
unused.
Where did you say I was?;
is the version that will appear if the alternative is "re-used". If
this second version is specified as a blank space only, the first
version of the sentence will always be used.
"one blank space"
The last semi-colon is followed by one, very important blank space,
which tells GRAAL there are no conditions attached to this dialogue
line.
To explain the concept of dialogue conditions, let's look at another
of the initially added lines, line 7. The definition of that LINE
goes:
1;7;Do you know anything about the ship in the harbour?; ;IFOF 2=1
First of all, notice there is no second version of this line. The
question will always look the same, regardless of how many times
Olaf puts it to the poor bartender.
Here, there is an additional condition that determines whether this
dialogue alternative is available to Olaf or not. Object flag 2 for
the bartender must be set to 1, otherwise the line will not appear
in the dialogue command area, no matter how many "DSET 1,+7"
commands are issued. However, once a DSET 1,+7 command has been
given, line 7 becomes a possible line: GRAAL will check object flag
2 for the bartender each time the dialogue is re-engaged or
refreshed, and as soon as flag 2 becomes 1, the line will appear and
become available for Olaf to speak.
If you look through the lines, you will notice that only lines 3 and
11 are unconditional. This means that if the first thing Olaf does
is engage in conversation with the bartender, only those two
alternatives will be visible. So what the player now sees in the
command area is:
What is this place?
My head hurts.
However, if he (which is unlikely) trundles off to the harbour to
look at the ship, and only then returns to talk to the bartender,
line 7
Do you know anything about the ship in the harbour?
is also available.
OK, back to our poor player, currently facing the task of choosing a
sentence to speak.
When the player clicks one of the alternatives, the corresponding
line number is sent back to GRAAL. Let's assume the player clicks on
My head hurts.
This means the number "11" is returned. GRAAL now starts to search
for LACT statements starting with 1;11; - there had better be one,
or nothing will happen! Fortunately, there is:
LACT: 1;11;RESP R,1,That's probably because...;DSET 1,N11
This is a typical example of a simple response to a dialogue line.
The bartender speaks, and then another DSET command is given.
Because we already are in dialogue mode, this command only
"refreshes" the dialogue - that is, makes alterations to the current
set of valid alternatives. In this case, the adjustment is to take
away line 11 and tell GRAAL that it should never been shown again.
That's what "N11" means.
Assuming Olaf hasn't been out exploring the town yet, he is now left with
only one alternative - the line
What is this place?
The response to this one is a bit more substantial. The bartender
makes a long response - so long, in fact, that is does not fit into
one LACT statement with ease. Instead, there are two statements,
performed in sequence. When using this technique, remember NOT to
put an EXIT or DSET command at the end of the first statement,
because that would interrupt the process and prohibit the second
statement from being executed!
In the process, the bartender - if he is still named "bearded man" -
reveals his identity. Therefore, there is a
NAME bartender;
command, renaming object 5 "bartender" if it has not been done
already.
The response ends with DSET 1,+1,+2,+5. This means that three more
possible alternatives will be added to the set of lines available to
Olaf, all of which are unconditional. The current alternative - line
3 - also remains, but now appears in its alternative form "Where did
you say I was?". This makes the conversation a bit more believable,
since you usually rephrase your questions when you feel you need to
repeat them.
One of the added alternatives, line 1, is an "end-of-conversation"
alternative. When Olaf says "Thank you very much", the bartender
answers "Don't mention it.". Then,
EDLG;EXIT
is performed, which switches the game back to normal input mode. As
you se in the LACT statement, object flag 1 for the bartender is set
to 1 to indicate that if we TALK TO the bartender again, it is a
resumed conversation - the initial "hellos" will be expressed a bit
differently.
See the on-line reference for information about the SETOF command.
We can use the simple form of the SETOF statement to set the
bartender flag because all throughout a dialogue, OBJ1 points to the
object we talk to. OBJ1 is normally the first object pointed to by a
command sentence. In other words, after we specify
TALK TO BARTENDER, OBJ1 remains pointing to the bartender until we
resume normal input mode again.
This concludes the basic tour of the features available in GRAAL
1.0, but stay tuned: Below are a lot of hints and tips about how to
use the power and special techniques of GRAAL to their full
potential.
11 MASTER CLASS: CHARACTER AND GRAPHICS DESIGN
==============================================
Well, fellow adventurer, by now you are a proficient GRAAL user.
I hope. Anyway, welcome to the first master class, where we will
look at some of the central GRAAL concept a bit more closely.
This chapter deals with designing your main character and planning
your graphics, something that must be done with some thought and
consideration - although small adjustments are easy to make at any
stage during the game development, things like the character size
influence every other piece of graphics you create, so beware!
11.1 SIZE
---------
Get a suitable character size, keeping the backgrounds in mind -
they are 120 pixels high, and in lowres, so you must use lowres when
designing too - otherwise your hero will look rather fat on the
screen! I should think a character between 40 and 60 pixels high
would be about right. Below 40 and there is not much room for detail
at all, more than 60 and the scenes start to feel cramped because
the character takes up too much space. Also, bigger graphics takes
more processing power.
In addition, the more pixels you have to animate, the more chances
you have of making a bad job of it! Really, I am not kidding. Small
can be beautiful sometimes.
Naturally, how you want the backdrops to relate to the main
character is also a factor - is he a small guy in a big, cruel
world, or an ace detective always moving around in cramped Victorian
tunnels and Baker Street studies?
11.2 COLOUR
-----------
Use only some of the available colours for your character, and make
it a good spread of useful colours, because these colours will have
to be the same in all scenes!
Colours not used for portrayal of the main character, or frequently
occurring objects, can change according to the current scene - the
more colours you have left to play with, the more variation you can
bring to the backdrops.
Note: The first three colours more or less have to be as follows:
Colour 0 should always be used ONLY for transparent areas in BOB
images. Colour 1 SHOULD be a rather bright white, colour 2 MUST be
black!!
Here's a tip: When working with a background or clip-art picture in
a paint program, set colour 0 to something strange to distinguish it
from "usable" colours, but always set it back to black before
saving, or the borders around the adventure scenes when running the
adventure may become coloured in ways that we don't want! If you
don't follow this advice, you surely will make the mistake of using
colour 0 as the black colour in spots of the graphics, whereas it
will be transparent when used in the game - and vice versa!
Despite the fact that you should only use some colours for the
character, always create the graphics with a 32-colour palette (=5
bitplanes).
11.3 DESIGNING ANIMATIONS
-------------------------
The following poses must be designed for the main character:
* The stills to use for front, back and "sideways facing left"
still poses.
* The animations for walking towards, away, and sideways right to
left.
* The animations for talking corresponding to the front, back and
side stills. (Open and close the mouth in different ways, move
the head slightly, etc.)
* The animations or stills used for handling objects (picking up,
handing over, etc.), also corresponding to the three "main
stills" previously mentioned, but in three different heights for
each still - High, Middle and Low, depending on whether the
object is located on the floor, high up or on a table or
something else in "mid air".
The reason you don't have to make separate animations and images for
right and left is that you can mirror one image to point in the
other direction using a simple trick described further on. This
saves memory as well as time spent in paint programs!
To get the animation smooth, it should be designed to work with
frame updating taking place every 6th vertical blank. This may sound
like nonsense to you, but what it means is that you can switch the
animation cel every six 50ths of a second, which equals six frames
displayed on a PAL TV system (or 60ths of a second on an NTSC
system).
Actually, too many animation cels for a certain movement may not
necessarily add that much to the game anyway. Olaf uses only 5 cels
for a basic walking movement, each cel being shown for 6 50ths of a
second.
So, now you should have you basic animations designed. Good. First,
test them against some different backdrops that you think will be
representative for the game in your excellent paint program.
Then, satisfied that your character basically looks OK, you should
now design a "dummy room" in GRAAL, place some "dummy objects" in
that room that will force your character to use all his newly
learned physical skills. Then, give him a good work-out.
11.4 ALL ABOUT 3D AND HOTSPOTS
------------------------------
GRAAL rooms are usually displayed in a "simulated 3D" perspective
(although top-down views can be achieved). This basically means
that the things slightly higher up the picture seem "further away"
than the tings towards the lower end of the picture. Take the
harbour in "Olaf" as an example: When Olaf walks towards the water
and the edge of the quay, he's actually only moving a number of
pixels up the screen - there is no such thing as "away", because the
screen can never really be anything but 2D.
This simple fact allows us to play with foreground and background
objects. Anything placed towards the bottom of the screen will, generally
speaking, be "in front". I'm talking about objects as well as STATIC: and
ANIM: images now, mind you - everything drawn directly onto the
background picture will naturally always be part of the background!
So, as a rule anything lower down goes "in front" of anything further up,
but that's not necessarily the way we want people to perceive things -
take the mug on top of the barrel in the bar, for instance. Looking only
at the placement of the images of the mug and the barrel, the mug should
logically be partly hidden by the barrel, because it is further up the
picture. It's not. Instead, it looks like it is placed ON the barrel,
which is what we want. Also, when Olaf walks behind the barrel, he must
also walk behind the mug - if the mug is on the barrel but Olaf seems
to be walking in front of the mug but behind the barrel, everything
becomes hideously unrealistic.
The answer to this problem? It's simply a matter of setting each image's
hotspot correctly. The hotspot is the point of each image that tells
which point of the image will actually be placed at the x and y
coordinate specified for an object.
Each image has its own hotspot, and it is normally set when the image is
loaded with a ...BOBS: statement (the last parameter - look it up in the
reference). The GRAAL default is to place the hotspot at the middle of
the bottom edge of the image - you might say at the "foot" of the image.
This is normally very appropriate, especially so for people and living
objects. But you can place the hotspot anywhere you like - if you specify a
value other than the default, the hotspot will be offset in the y direction
that number of pixels from the top edge of the image. Both negative and
positive values are allowed.
Study the ROOMBOBS: statement for the mug image in room one, compare that
to the mug's x and y position in the OBJECT: statement in graal.main, and
you will see that the hotspot is placed well below the actual image, making
it the "frontmost" object in the bar.
The hotspot of an image can also be altered using the HOTSP command -
this is used in some cutscenes dealing with the ship in the harbour,
to switch the depth-placing of the sail. This is because the captain
first walks behind the sail, but when summoned ashore, he suddenly has
to go in front of it! The solution? Just alter the sail's hotspot...!
12 MASTER CLASS: CUTSCENES
==========================
CUTSCENES are simply script files (suffixed with .scene) that contain
nothing but commands. That's right - no conditions, and no statements!
This means lines should NOT start with ACTION: or anything like that -
just fire away with the command name in column one of each line!
The immense usefulness of cutscenes may not be apparent at first,
but you will soon find out that you use quite a lot of them -
because in addition to being used for "movie scenes", they are also
very handy whenever you have a sequence of GRAAL commands that you
need to use in a lot of different places. In these cases, cutscenes
can act the way procedures or subroutines do in ordinary programming
languages. In those cases, you must make sure all of the cutscene is
executed, and you probably don't want to show the cutscene indicator
to the player. It's easy enough - just read on!
The logic of cutscenes ought to be a fairly simple subject, since
there are no conditions allowed in them! In practice, two things
require you to think very carefully about designing your cutscenes:
The "skip" function (pressing the <Esc> key to jump past a cutscene)
and nested cutscenes.
12.1 HOP, SKIP AND JUMP
-----------------------
Normally, a cutscene consists of two parts: The main part at the
top, always containing ALL the actions in the scene, and the FINAL
section at the end.
The FINAL section is ONLY used if the <Esc> key was pressed during
execution of the main part. It must duplicate all statements
necessary to set the scene exactly the same way it would have been
set if the main part had been run through completely. Remember, you
never know exactly where in the flow of the main part the player
decides to press <Esc> and breaks out of the action!
12.2 NO BREAKS!
---------------
In some circumstances, for example when you use cutscenes as
"subroutines" as discussed above, you may not want the skip option
to be in effect. In this case, start the entire cutscene with the
cutscene statement NOBREAK, which disables the <Esc> key for the
duration of the cutscene. If a cutscene starts with NOBREAK, you
don't need a FINAL section in it.
12.3 NESTING
------------
Now, to complicate things even further, cutscenes may be nested in
up to three levels - that is, you can execute a cutscene within a
cutscene from within a cutscene!
"Why on earth would I want to do that?" you ask. Well, a good
example is the harbour scene in room 3 of "Olaf". There are a number
of occasions when Olaf needs to interact with the captain, calling
him ashore time and time again. The captain's going ashore and
aboard can not be handled as simple PTRN sequences, because he, the
ship itself, and the sail need to be rearranged in various ways to
make the captain go behind the sail, in front of the sail but behind
the gangplank, etc.
Therefore, the captain going ashore is played using one cutscene,
the going aboard in another (well, actually two, depending on
whether his hat is secured with the rubber band or not). These
cutscenes are then used from within, or in conjunction with, a
number of others specifying what is going on when the captain comes
ashore to talk to Olaf.
Let us call the first cutscene the "master scene" and those called
from within that "sub-scenes". Now, what we have to watch out for is
this:
If we press <Esc> at the very beginning of the master scene, or
indeed anywhere before the last sub-scene, this means some of the
sub-scenes will not come into play at all. However, the contents in
each sub-scene may affect how the game should be set up at the end
of the master scene.
To conclusion is that the FINAL section of the master scene also
must include all statements that are present in the FINAL sections
of the relevant sub-scenes. Let's look at Olaf and the captain
again, when Olaf tries to use the dictionary on the captain and gets
it all wrong. This is depicted in CUTSCENE 13 structured like this:
1. First, CUTSCENE 2 is called as a sub-scene to make the captain
come ashore.
Note: Sub-scenes should always be called with parameter ,F to
stop the cutscene indicator symbol flickering on the screen. The
master scene should be called with parameter ,S because when
it's finished, the whole scene is finished.
2. Then, Olaf tries to speak hindi or something like that, and gets
punched out.
3. While Olaf is still on the ground recovering, CUTSCENE 3 is
invoked to put the captain back aboard the ship.
4. Once the captain is back aboard, Olaf gets up and notes that the
whole endeavour wasn't particularly successful.
5. The FINAL section of the master scene CUTSCENE 13 then needs to
contain the following: The commands from the FINAL section of
CUTSCENE 3, because those make sure the captain is back in place
aboard the ship, and some commands to put Olaf back on his feet
in the right position. We do NOT have to bother about anything
in CUTSCENE 2, because the captain's coming ashore does not have
anything to do with how things look after the master scene is
finished.
13 MASTER CLASS: SPECIAL TECHNIQUES OR
"HOW THE HECK DID HE DO THAT?"
=======================================
This is a walk-through of some of the particularly clever stuff in
the Olaf script files. I hope it goes to prove that I have tried not
only to solve specific "Olaf" problems when writing GRAAL, but
provided a set of commands that are flexible enough to allow even the
nearly impossible to be done without an endless array of novelty gadgets
of limited use.
13.1 SPEAKING IN A FOREIGN TONGUE
---------------------------------
The conversation with Rajah Singh on the quay is rather special -
you are forgiven for thinking a special font is being used to
display the foreign language of Rajah. However, this is not the
case. Instead, I have combined a "blank" RESP command with BOBON and
BOBOFF commands. Have a look in the 3.room file:
First, the "foreign language" was "written" in an ordinary picture
(3FG.IFF) using DPAINT.
Then, the "words" were grabbed as RBOBs using ROOMBOB statements.
Rajah's responses to Olaf dialogue lines are as follows:
First, a BOBON command is used to display the RBOB with the "foreign
language".
Immediately upon that, a RESP command displaying nothing but blank
spaces is used to make Rajah Singh "speak".
After that, a BOBOFF takes away the strange text again. Simple, eh?
No need to construct an entire font (and no need for another GRAAL
command to handle that font!).
13.2 AN AUTOMATED ROOM
----------------------
As you may have noticed, you can never get into normal game mode in
Ali Harrod's shop - As soon as you walk in, you end up in dialogue
mode, and when you end the dialogue, you are immediately transported
out of the boutique. This is thanks to the DACT statements, where
the programmer can grab control and keep it for as long as he likes!
Have a look in 4.room - there is not a single run-through of DACT
statements that does not end with a DSET... EXIT combination,
forcing the player into dialogue mode. Therefore, there are no ACTION:
statements either.
This technique is useful in a lot of circumstances - many times, it
relieves you of having to think out a lot of elaborate ideas for a
room where you really don't want the player prowling around.
13.3 THE ART OF AVOIDING A SEAGULL
----------------------------------
As long as the seagull in the harbour is sitting on the pollard,
Olaf steers well clear of it when walking about. He simply walks
where the room file FLOOR: statements say he can move!
However, as soon as the seagull is scared off, Olaf is free to
approach the pollard and pick up the feather. This is made possible
by two FLOOR and one NFLOOR command executed in the cutscene where
the seagull takes off (4.scene).
Having chased the seagull away, one problem remains: The next time
we re-enter the room, we want things to be the way they are now, and
not according to how they are set up in the room file statements.
A room flag comes to the rescue here - it allows us to "remember"
the seagull status between visits to the room.
Room flag 1 for the room (room 3) is used - as long as it is zero
(the initial state), the seagull is on the pollard. As soon as the
bird is scared off, we set the flag to 1 with a SETRF 1=1 command in
the cutscene. This room flag is tested in a DACT: statement - if it
is set to 1, the bird is moved to the roof of the shed, and the default
floor definitions are changed exactly the same way as in cutscene 4.
Remember, as long as the LIGHTS ON command has not been used, the scene
remains black and we can move anything we want around without the player
being aware of what is done!
13.4 A SPITTING IMAGE
---------------------
The spitting llama on offer by Ali Harrod is composed of two
animations, because I decided a single one would be too large.
Instead, the llama itself is one animation, and the "spit" is
another, very small one, animated by an AMAL "Move" command.
The movement of the llama and spit animations are synchronised - the
llama being displayed on top of the spit. (Well, almost synchronised.
If you leave the llama sequence on and walk away for a quarter of an
hour, you will notice that things have become a little strange when
you return. But who could keep away from the game that long, anyway?
And if you don't like it, you can always make one big animation of
the whole thing!)
13.5 A MAP ROOM
---------------
I had planned on only delivering the first four rooms with GRAAL,
but ended up giving you seven. The reason is some quite interesting
techniques were used in rooms 5 and 7, which may come in handy.
Room 5 is an outline map of the East, showing the towns of
Constantinople, Gurgan and Baghdad. The thing is, there is no Olaf,
and nothing to do except watch a short cutscene and, when
revisiting, point to one of the three towns.
Olaf was done away with by a simple CHAR OFF command in a DACT
statement - nothing strange about that (once you read the on-line
reference). Remember that the main character will always be made
visible when entering a new room, unless you put it away again with
CHAR OFF.
There are no objects in the room, and although you can try to
manipulate the objects in the inventory, whatever happens will not
get through to you, because Olaf is not there to tell you about it.
However, three small exits placed just over the towns on the map
provide three ways to get on with the game.
I have chosen to display the exit names the normal way, although I
might just as well have put a blank space instead of names in the
EXIT statements - the names of the towns are written on the map, and
it shouldn't have taken the player too long to figure out where to
click, anyway.
13.6 A SMALL GUY
----------------
Character scaling is not well supported in GRAAL at the moment, but
thanks to the system's flexibility, you can (partially) ignore that!
To prove it, I have made a big Baghdad panorama in room 7, requiring
Olaf to be shown at half the normal size.
Tough job? Not very. The secret is the BOBS command, which can be
used to switch the global BOB images to a new size. I simply took
the Olaf_Original.IFF picture containing the standard animations for
Olaf, halved its size, and re-saved it under a different name. When
Olaf arrives at Baghdad, all graphics are replaced using BOBS
commands and the new picture CLPART file. In addition, for this
sunset scene I also altered the colour scheme for the Olaf images
slightly. It blends better with the background picture that way.
There is one problem here which you must be aware of:
Loading saved games does not automatically restore global BOB images.
So, if you are in Baghdad (Olaf small) and load a saved game placing
him in, for example, room 2, he will still be small. Or would be, if
we did not do anything about it.
Well, this is not too difficult to take care of. In fact, in GRAAL 2
there is a new function making it even easier than it used to be.
Each time GRAAL loads a stored position (or executes the RESUME command,
which is, in effect, a "load from RAM:"), it immediately looks for
ACTION: statements containing the special "verb" -2.
This means that all we need is an ACTION: -2;... statement in the
graal.main file being able to determine whether the global BOBs should
be reloaded or not.
To achieve this, and keep track of Olaf's looks, I used a room flag
belonging to room 0. Room 0 is a "dummy" room which is never used in
a game, so there are actually 20 excellent "global" room flags
there, which can be used to keep track of "global game states".
So, if room flag 1 for room 0 is 1, (i.e. IFRF 0,1=1), Olaf needs a
change of clothes. The change is taken care of by some BOBS
statements in a cutscene file, restoring the original BOB images.
And that's that.
Like this:
ACTION: -2;IFRF 0,1=1;CUTSCENE 17,H
and the contents of 17.scene is simply:
/* The correct graphics file
CLPART Olaf_Original.iff
/* Some BOBS commands to load the images
BOBS 10;11;...
...you get the picture. (And so does GRAAL.)
14 MASTER CLASS: HINTS AND TIPS
===============================
Here are some general hints and tips that may prove useful.
14.1 FLAGS
----------
* Avoid setting flags in cutscenes, if you have a choice. It's hard to
keep track of the games' status in the main script files if the
setting of flags is "hidden from sight" in the cutscenes. (And
forget I mentioned I've done just the opposite in a few places. Do
as I say, not as I do! :-)
* Since all variables have the initial value 0, it is good practice to
let that value represent the initial state of the object, room,
situation, etc.
* Use room flags for all things that relate to the scene as a whole,
rather than the flags of a particular object.
* Remember that ALL aspects of room objects and section objects get reset
as soon as you leave the room or section. You can compensate for this
using room flags to track room object states, and then set the objects
up in whatever way they should be by using DACT statements.
15 QUESTIONS AND ANSWERS
========================
Q: Anything I should think about when assigning BOB numbers to
objects?
A: Use numbers below 60. Make sure a BOB number is never used for
more than one thing at a time in the same room. Otherwise, no: No
information is connected to or "belongs to" BOB numbers and their
use, so there are no other fixed rules.
Q: What about animation channels then?
A: Same thing. Look up the reserved channel numbers in the on-line
reference, and make sure you never try to use the same channel for
two things in the same room!
Q: What are the rules for room object use?
A: A room object can only exist in one room - therefore, it can
never be picked up or added to the inventory. Nor may you use its
object flags for very much, because they will be reset each time you
exit the room.
ROBJ references should only exist in .room files, never in .sect or
graal.main!
Q: What are the rules for section object use?
A: A section object only exists within one section, and preferably
disappears totally during the first visit to the section -
otherwise, you must keep track of how the objects have been handled
via room flags or such devices, if you happen to re-enter the
section.
In other words, take particular care if your adventure is designed
in such a way that you can go back to, for example, section 1 from
section 2 - not only must you be sure that section 1 still looks
okay with respect to section object use, but also, the section 2
section objects will suffer the same problems! Even if you haven't
"solved" section 2 yet completely, going back to section 1 will end
your first visit to section 2 and thus reset your section objects for
section 2!!
SOBJ references should only be used in .room and .sect files, not in
the .main file.
Q: I need some very precise movement paths for my character in some
situations, and the floor system is not quite up to the job.
A: There are a couple of ways.
A) Try the PATH: statements (new to GRAAL 2). These allow you to
connect otherwise unconnected floors using "twisting" paths. Read more
in the room PATHS: statement in the on-line reference.
B) Use an un-named exit! When you specify an EXIT: with no
description, GRAAL shows no exit name in the scene area, nor does it put
a "Go to ..." message in the sentence box when the exit is clicked. That
way the un-named exit is just a "clickable area" in the scene area, and
you can use ACTION: 0;... statements for it to do anything you like.
1. Put an un-named exit over the destination on the screen your character
should reach using a special movement or animation.
2. In the ACTION: statements, use whatever commands you need to transport
the character to the destination point: Perhaps first an ordinary
CMOVE to the closest edge of the actual floors, and then OMOVE 0...
to make the final part (up the ladder, down the hole, or whatever).
Note: Remember, if you move the character outside the normal floor area,
you are in a bit of trouble if he must also be able to return: If
you click outside your unnamed exit, the normal floor system will try to
move the character the normal way, and if it is no longer in any floor
area... well, problems arise. They can be dealt with, though, using some
careful planning. The easiest way is to make sure the player does not get
the opportunity of clicking anywhere before the character is safely back
on a legal floor again! Some clever use of a number of un-named exits
together with SHOW EXIT and HIDE EXIT commands may do the trick.
Q: I have the need for menu-style pictures with multiple user options.
A: Yes, why not indeed? Just use EXIT: statements with no name/description
to define the clickable areas needed on screen, and then ACTION: 0;...
statements to handle the player input. Or, define room objects that are
actually buttons.
Q: I want a way to show the player's score at any time!
A: In GRAAL 2, the neatest way is probably to put a "SCORE" button in the
command area using the VERB_ZONE: and VERB_TEXT: statements in the
graal.main file. VERB_TEXT: allows you to define "direct verbs", that is,
commands that do not wait for or use an object. If you define a verb
"SCORE" and make that a direct verb, you can then use a TEXT command
to display the score held in a flag (preferably a room flag for room 0
- as mentioned elsewhere, these make excellent "global flags").
Q: I want an object / person to follow my character around.
A: There is no direct support for this in GRAAL. However, if you plan
the thing carefully, you may be able to use one of the timers (see the
documentation of the DOAFTER command), and the "character offset"
abilities of the OMOVE command to move things relative to the main
character independently of the player input. Just keep in mind that
only the main character makes use of the floors and paths defined...
Q: I want to do some advanced arithmetics, using the contents of one
variable to alter another and so on.
A: Yes, OK, OK. You can do a lot more stuff with flags, values, and
comparisons in GRAAL 2 than was possible in GRAAL 1. Still, be very
careful when using this freedom. Too much random number-juggling
in flags have a tendency to make the number of possible alternatives
so large that the game becomes difficult to test, and needs a lot
of ACTION: statements to cover all possibilities.
Q: I don't quite understand the FLOOR: statements.
A: The best description is in graal.guide. Make sure you read ALL the
information about FLOOR: there - it's even got some diagrams! Then
look at one of the rooms in the demo adventure to put theory to practice.
Q: I'm trying to run the GRAAL editor and GRAAL in parallel, but changes
I make to the scripts in the editor do not seem to take effect, even
though I'm sure I have saved them to disk.
A: 1. You must exit the room / situation where updates were made and
then re-enter to force a reload of the scripts in question. Alter-
natively, use the "Go to" button in the on-line monitor, which
also forces a reload.
2. You must have MAX_CACHE: 0 in graal.main before starting GRAAL for
this. Otherwise, an old copy of the script file still in memory
will probably be used instead of your updated version.
3. Changes to graal.main NEVER take effect without restarting the game.
So there.
Q: My tunes play in a strange tempo!
A: GRAAL only supports the "old" soundtracker tempo format of "ticks" -
the primary tempo should always be 33, and the secondary can be
altered using tracker commands to achieve the desired tempo. (Between
5 and 7 is usually good.) Any attempt to use BPM settings instead will
get you into trouble for sure.
Q: After playing a tune with the TRACK command, samples played with the
SAM command get caught in a loop!
A: Naughty you - you have used an undocumented feature of GRAAL! It CAN
play med modules (MMD0 and MMD1 formats), provided you have the file
extension ".med" in the module name. However, this causes the above bug
in the sample routines to appear - this is Amos's fault. I know there
exists an Amos bugfix or work-around for this, but I DON'T HAVE IT.
If anyone has seen it, mail it pronto, and the med support will be made
official!
SUPPORT TOOLS
=============
A THE ON-LINE MONITOR
=====================
GRAAL_2 is equipped with an on-line monitor able to show you the
values of all flags and states of all objects. Simply press the [G]
key during testing, and voilà - a screen drops down covering
everything else.
The monitor has three sections: Object, Room and Dialogue Control. You
will use the Object and Room Control most frequently. Let's go through
it all one step at a time:
A.1 OBJECT CONTROL
------------------
All current objects - that is, the global objects and the objects for
the current section and room - are shown in the list. Click on one to
select it, and information about its location and value for flag 1 is
shown in the other fields and gadgets.
To see the values for the other object flags, click on the "Flag"
cycle gadget. To set a new value for a flag, enter a new value in the
"Value" fields, and click the "<-Set" button.
The best way to add objects to the inventory is to select the object
in the list and the click the "<-Pick" button. This sets the room to
999, which is the room used for the inventory.
A.2 ROOM CONTROL
----------------
When you call the monitor, the Room and Entrance fields show the room
and entrance numbers used in the last GOTO command.
To switch to a new room, type the room number in the Room field and
press [Enter]. Note that you must press [Enter] for the data for the
desired room to be available in the flag Value field.
To set a new flag value for a room flag, proceed the same way as with
object flags.
One of the best things about the monitor is that it allows you to jump
instantly to any room and entrance you desire during testing. Simply
type in the room and entrance numbers, and the press the "<-Goto"
button. The monitor will disappear and the selected room will be
loaded.
If you have set MAX_CACHE to 0, using "<-Goto" is also a very handy
way of reloading a room script - pressing "<-Goto" without changing
rooms will still reload the room script, and that will force any
changes to take effect immediately.
A.3 DIALOGUE CONTROL
--------------------
To be honest, I haven't used this option that much. Basically, it
allows you to investigate the status of the lines in a dialogue -
which could be handy at times, because it is the line state that
determines whether a dialogue line is able to pop up in the set of
dialogue lines.
A.4 BACK TO GRAAL
-----------------
The "Back to GRAAL" button quits the monitor and returns control to
the game. If any changes were made to flag values etc. in the monitor,
GRAAL will reload the current room. This is because changes may affect
the way objects and stuff in general are set up in the DACT
stataements.
B MACROS
========
Macros are new to GRAAL 2.0. They allow you to record a sequence of
player input selections, store them in a file, and play them back later.
The primary use is for testing - being able to play the same sequence of
events back over and over again, and having it done automatically, makes
testing a whole lot easier. They are especially useful for running
through parts of the game which are really "finished", but still need
to be tested from time to time to check that no alterations you have
made to other parts of the game affects them.
The macro functions only work in development mode - once the keyfile
is in place, they are not available.
B.1 Starting a macro recording
------------------------------
1. Start the game. Load a saved game, or go to the position from which you
want to start the macro recording by playing the game in the normal
way.
2. Press the [R] key. A message telling you that macro recording is activated
is shown very briefly in the scene area.
3. From now on, every command you execute, and every exit or dialogue line
you choose, will be recorded to memory.
B.2 Saving a macro
------------------
1. When you have reached the point where you want the macro to stop, press
the [R] key again.
2. A dialogue box pops up, asking for a macro file name. The name you type
will be suffixed with the text ".macro"
3. Click the "Save" button. The macro file is now stored in the development
directory.
B.3 Playing a Macro
-------------------
1. Make sure the game is in EXACTLY THE SAME POSITION as when you started
the macro recording. Preferably, you have a saved game position to load
to ensure this.
2. Press the [P] key. A dialogue box appears, asking for the macro file
name. Type the name - you do not have to enter the ".macro" part.
3. Click the "Load" button.
4. The contents of the macro are now re-played before your very eyes.
Sit back, watch, and enjoy!
5. You may abort the playing of the macro at any time by pressing the
[Esc] key between commands.
B.4 Restrictions
----------------
The original timing of the player input is not preserved in the macros.
When a macro is played back, execution of the next command starts as soon
as the previous is finished. This means macros are not suited for recording
parts where the timing of player input is critical. In other words, if
you are using the new GRAAL 2 timer functions, stop to think before you
record macros - is the timing in the sequence going to affect the result
of the playback or not?
C "PRODUCTIFYING" YOUR ADVENTURES
=================================
Read the file "prod.text" for an explanation of how to get your adventure
onto diskettes.
D THE EDITOR
============
GRAAL sports its very own script editor, called GRAAL_Editor. It is
documented in the file Editor.text.